// WndListTime.cpp : implementation file
//

#include "stdafx.h"
#include "BBViewer.h"
#include "WndListTime.h"

#include "StatusMgr.h"
#include "../_inc/def_interface.h"

// CWndListTime
IMPLEMENT_DYNAMIC(CWndListTime, CWnd)

CWndListTime::CWndListTime()
{	
	m_bInitList = FALSE;
	m_bChecked = FALSE;

	int i;
	for (i=0;i<MAX_REC_TYPE;i++)
		m_bRecType[i] = TRUE;
	m_bSorted = FALSE;
	m_pListMgr = NULL;

}

CWndListTime::~CWndListTime()
{
}


BEGIN_MESSAGE_MAP(CWndListTime, CWnd)
	ON_WM_SIZE()
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_SHOWWINDOW()
	ON_NOTIFY(HDN_ENDTRACK, 0, OnEndtrackSkinList)
	ON_WM_ERASEBKGND()
	ON_MESSAGE(WM_CTL_MESSAGE, OnCtlMessage)
	ON_MESSAGE(WM_PLB_MESSAGE, OnPlbMessage)
	ON_WM_DESTROY()
END_MESSAGE_MAP()



// CWndListTime message handlers



int CWndListTime::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	LPST_WND_POS lpWndPos = theApp.WndPos.GetAt(wpListTime);
	m_nMode = lpWndPos->nMode;

	if (!m_SkinList.Create(WS_CHILD|WS_VISIBLE|LVS_REPORT , CRect(0, 0, 0, 0), this, IDC_LIST_TIME))
		return -1;	

	if (!m_ListDate.Create(WS_CHILD|WS_VISIBLE|LVS_REPORT, CRect(0, 0, 0, 0), this, IDC_LIST_DATE))
		return -1;

	if (!m_ListHour.Create(WS_CHILD|WS_VISIBLE|LVS_REPORT, CRect(0, 0, 0, 0), this, IDC_LIST_HOUR))
		return -1;

	m_nFontHeight = 14;
	LOGFONT lf;
	lpWndPos = theApp.WndPos.GetAt(wpListTime);

	ZeroMemory(&lf, sizeof(lf));
	lf.lfHeight = m_nFontHeight;
	lf.lfWeight = FW_NORMAL;
	wcscpy_s(lf.lfFaceName, sizeof(lf.lfFaceName)/sizeof(lf.lfFaceName[0]), DEFAULT_FONT);
	m_ListFont.CreateFontIndirect(&lf);

	m_ListDate.SetFont(&m_ListFont, TRUE);
	m_ListDate.Init(FALSE, m_nFontHeight);
	m_ListDate.SetBkColor(lpWndPos->dwColorBackground);
	m_ListDate.SetTextColor(lpWndPos->dwColorText);
	m_ListDate.SetItemIndicateColor(lpWndPos->dwColorLevel[0]);
	m_ListDate.SetItemColor(lpWndPos->dwColorLevel[1], lpWndPos->dwColorLevel[2]);

	m_ListHour.SetFont(&m_ListFont, TRUE);
	m_ListHour.Init(FALSE, m_nFontHeight);
	m_ListHour.SetBkColor(lpWndPos->dwColorBackground);
	m_ListHour.SetTextColor(lpWndPos->dwColorText);
	m_ListHour.SetItemIndicateColor(lpWndPos->dwColorLevel[0]);
	m_ListHour.SetItemColor(lpWndPos->dwColorLevel[1], lpWndPos->dwColorLevel[2]);

	m_SkinList.SetFont(&m_ListFont, TRUE);
	m_SkinList.Init(TRUE, m_nFontHeight);	
	m_SkinList.SetBkColor(lpWndPos->dwColorBackground);
	m_SkinList.SetTextColor(lpWndPos->dwColorText);
	m_SkinList.SetItemIndicateColor(lpWndPos->dwColorLevel[0]);
	m_SkinList.SetItemColor(lpWndPos->dwColorLevel[1], lpWndPos->dwColorLevel[2]);


	return 0;
}

void CWndListTime::InitListCtrl()
{
	// List Control
	int nWidth1, nWidth2, nWidth;
	int i;
	nWidth1 = (m_nListWidth-20)*4/7;
	nWidth2 = (m_nListWidth-20)*3/7;

	nWidth = m_nListWidth-(nWidth1+nWidth2+20);
	for (i=0;i<nWidth;i++)
	{
		if ((i%2)==0)
			nWidth1++;
		else
			nWidth2++;
	}

	if (m_bInitList)
	{
		m_ListDate.SetColumnWidth(0, m_nDateWidth);

		m_ListHour.SetColumnWidth(0, m_nHourWidth);

		m_SkinList.SetColumnWidth(0, 20);		//fixed
		m_SkinList.SetColumnWidth(1, nWidth1);
		m_SkinList.SetColumnWidth(2, nWidth2);

	}
	else
	{
		//1.Date
		m_ListDate.InsertColumn(0, m_pListMgr->GetString(0), LVCFMT_CENTER, m_nDateWidth);

		//2.Hour
		m_ListHour.InsertColumn(0, m_pListMgr->GetString(1), LVCFMT_CENTER, m_nHourWidth);


		m_SkinList.InsertColumn(0, _T(""), LVCFMT_CENTER, 20);		//fixed
		m_SkinList.InsertColumn(1, m_pListMgr->GetString(2), LVCFMT_CENTER, nWidth1);
		m_SkinList.InsertColumn(2, m_pListMgr->GetString(4), LVCFMT_CENTER, nWidth2);

		m_ListDate.DeleteAllItems();
		m_ListHour.DeleteAllItems();
		m_SkinList.DeleteAllItems();
	}

	m_bInitList = TRUE;
}

void CWndListTime::OnPaint()
{
	CPaintDC dc(this);
	CRect rect;
	CBitmap bmp, *pOldBmp;
	CDC dcMemory;

	CBitmap *pBmpBg, *pOldBmpBg;
	CDC dcBg;
	LPST_BMP_INFO lpBmpInfo = theApp.BmpInfo.GetAt(biListBG);
	LPST_WND_POS lpWndPos = theApp.WndPos.GetAt(wpListTime);
	CRect rtDiv = lpWndPos->rtDiv;
	CRect rtImg = lpBmpInfo->rtImageRect;

	if (lpBmpInfo->hbmpImage == NULL)
		return;

	this->GetClientRect(&rect);

	bmp.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
	dcMemory.CreateCompatibleDC(&dc);

	pOldBmp = dcMemory.SelectObject(&bmp);

	dcBg.CreateCompatibleDC(&dc);
	pBmpBg = CBitmap::FromHandle(lpBmpInfo->hbmpImage);
	pOldBmpBg = dcBg.SelectObject(pBmpBg);

	dcMemory.BitBlt(0, 0, rtDiv.left, rtDiv.top, &dcBg, 0, 0, SRCCOPY);
	dcMemory.StretchBlt(rtDiv.left, 0, rect.Width()-(rtDiv.left+rtDiv.right), rtDiv.top,
		&dcBg, rtDiv.left, 0, rtImg.Width()-(rtDiv.left+rtDiv.right), rtDiv.top, SRCCOPY);
	dcMemory.BitBlt(rect.Width()-rtDiv.right, 0, rtDiv.right, rtDiv.top,
		&dcBg, rtImg.Width()-rtDiv.right, 0, SRCCOPY);
	dcMemory.StretchBlt(0, rtDiv.top, rtDiv.left, rect.Height()-(rtDiv.top+rtDiv.bottom),
		&dcBg, 0, rtDiv.top, rtDiv.left, rtImg.Height()-(rtDiv.top+rtDiv.bottom), SRCCOPY);
	dcMemory.StretchBlt(rtDiv.left, rtDiv.top,
		rect.Width()-(rtDiv.left+rtDiv.right), rect.Height()-(rtDiv.top+rtDiv.bottom),
		&dcBg, rtDiv.left, rtDiv.top,
		rtImg.Width()-(rtDiv.left+rtDiv.right), rtImg.Height()-(rtDiv.top+rtDiv.bottom),
		SRCCOPY);
	dcMemory.StretchBlt(rect.Width()-rtDiv.right, rtDiv.top, rtDiv.right, rect.Height()-(rtDiv.top+rtDiv.bottom),
		&dcBg, rtImg.Width()-rtDiv.right, rtDiv.top,
		rtDiv.right, rtImg.Height()-(rtDiv.top+rtDiv.bottom),
		SRCCOPY);
	dcMemory.BitBlt(0, rect.Height()-rtDiv.bottom, rtDiv.left, rtDiv.bottom,
		&dcBg, 0, rtImg.Height()-rtDiv.bottom, SRCCOPY);
	dcMemory.StretchBlt(rtDiv.left, rect.Height()-rtDiv.bottom,
		rect.Width()-(rtDiv.left+rtDiv.right), rtDiv.bottom,
		&dcBg, rtDiv.left, rtImg.Height()-rtDiv.bottom,
		rtImg.Width()-(rtDiv.left+rtDiv.right), rtDiv.bottom,
		SRCCOPY);
	dcMemory.BitBlt(rect.Width()-rtDiv.right, rect.Height()-rtDiv.bottom, rtDiv.left, rtDiv.bottom,
		&dcBg, rtImg.Width()-rtDiv.right, rtImg.Height()-rtDiv.bottom, SRCCOPY);

	dc.BitBlt(0, 0, rect.Width(), rect.Height(), &dcMemory, 0, 0, SRCCOPY);

	dcBg.SelectObject(pOldBmpBg);
	dcBg.DeleteDC();

	dcMemory.SelectObject(pOldBmp);
	bmp.DeleteObject();		//2013.04.29
	dcMemory.DeleteDC();
}

void CWndListTime::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	if ((cx==0)||(cy==0))
		return;

	//date:hour:list = 7:3:13

	LPST_WND_POS lpWndPos;
	LPST_BMP_INFO lpBmpInfo = theApp.BmpInfo.GetAt(biScrl_v_span);
	CRect rtStickTo;


	int nWidth, i;
	int nScrollWidth = lpBmpInfo->rtImageRect.Width();
	m_nDateWidth = (cx-nScrollWidth*3)*7/23;
	m_nHourWidth = (cx-nScrollWidth*3)*3/23;
	m_nListWidth = (cx-nScrollWidth*3)*13/23;

	nWidth=m_nDateWidth+m_nHourWidth+m_nListWidth+nScrollWidth*3;
	for (i=0;i<(cx-nWidth);i++)
	{
		switch ((i%3))
		{
		case 0:			m_nDateWidth++;		break;
		case 1:			m_nHourWidth++;		break;
		case 2:			m_nListWidth++;		break;
		}
	}

	if (m_SkinList&&m_ListDate&&m_ListHour)
	{
		lpWndPos = theApp.WndPos.GetAt(wpListTime_date);
		m_nLeftGap = lpWndPos->rtStickTo.left;
		rtStickTo = lpWndPos->rtStickTo;
		rtStickTo.right = cx - m_nDateWidth;
		theApp.SetWindowPosition(&m_ListDate, cx, cy, lpWndPos->rtWndPos, rtStickTo);
		m_ListDate.PositionScrollBars();
		m_nDateWidth -= m_nLeftGap;

		lpWndPos = theApp.WndPos.GetAt(wpListTime_hour);
		rtStickTo = lpWndPos->rtStickTo;
		rtStickTo.left = m_nDateWidth+12+m_nLeftGap;
		rtStickTo.right = cx-(m_nHourWidth+rtStickTo.left);
		theApp.SetWindowPosition(&m_ListHour, cx, cy, lpWndPos->rtWndPos, rtStickTo);
		m_ListHour.PositionScrollBars();

		lpWndPos = theApp.WndPos.GetAt(wpListTime_file);
		m_nRightGap = lpWndPos->rtStickTo.right;
		rtStickTo = lpWndPos->rtStickTo;
		rtStickTo.left = m_nDateWidth+m_nHourWidth+24+m_nLeftGap;
		rtStickTo.right += 12;
		theApp.SetWindowPosition(&m_SkinList, cx, cy, lpWndPos->rtWndPos, rtStickTo);
		m_SkinList.PositionScrollBars();
		m_nListWidth -= m_nLeftGap;

		InitListCtrl();
	}

}

void CWndListTime::OnShowWindow(BOOL bShow, UINT nStatus)
{
	CWnd::OnShowWindow(bShow, nStatus);

}

void CWndListTime::OnEndtrackSkinList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	HD_NOTIFY *phdn = (HD_NOTIFY *) pNMHDR;

	m_SkinList.UpdateHScrollPos();
	m_ListDate.UpdateHScrollPos();
	m_ListHour.UpdateHScrollPos();

	*pResult = 0;
}

void CWndListTime::UpdateDateIndexCal()
{
	
}

void CWndListTime::SetCheckAll(int nID)
{
	int i;


	if (nID == m_ListDate.GetDlgCtrlID())
	{
		for (i=0;i<m_ListDate.GetItemCount();i++)
			m_ListDate.SetCheck(i, TRUE);
		m_ListHour.SetHeaderCheck(CHECKED);
	}

	if ((nID == m_ListHour.GetDlgCtrlID())||
		(nID == m_ListDate.GetDlgCtrlID()))
	{
		for (i=0;i<m_ListHour.GetItemCount();i++)
			m_ListHour.SetCheck(i, TRUE);
		m_SkinList.SetHeaderCheck(CHECKED);
	}

	for (i=0; i<m_SkinList.GetItemCount(); i++)
	{
		m_SkinList.SetCheck(i, TRUE);	
	}

	if ((m_bChecked == FALSE)&&m_SkinList.GetItemCount()>0)
	{
		NotifyCheckStatus(TRUE);
	}

}

void CWndListTime::SetUncheckAll(int nID)
{
	int i;

	if (nID == m_ListDate.GetDlgCtrlID())
	{
		for (i=0;i<m_ListDate.GetItemCount();i++)
			m_ListDate.SetCheck(i, FALSE);
		m_ListHour.SetHeaderCheck(UNCHECKED);
	}

	if ((nID == m_ListHour.GetDlgCtrlID())||
		(nID == m_ListDate.GetDlgCtrlID()))
	{
		for (i=0;i<m_ListHour.GetItemCount();i++)
			m_ListHour.SetCheck(i, FALSE);
		m_SkinList.SetHeaderCheck(UNCHECKED);
	}

	for (i=0; i<m_SkinList.GetItemCount(); i++)
	{
		m_SkinList.SetCheck(i, FALSE);	
	}

	if (m_bChecked == TRUE)
	{
		NotifyCheckStatus(FALSE);
	}
}

int CWndListTime::GetListItem(int nStartCount)
{
	if (nStartCount>=m_SkinList.GetItemCount())
	{
		CTimeList *pItem;
		if ((m_nPlayListStart+nStartCount)>=m_arrPlayList.GetSize())
		{
			return -1;
		}
		else
		{
			pItem = m_arrPlayList.GetAt(nStartCount+m_nPlayListStart);
		}

		time_t tStartTime = pItem->GetStartTime();
		time_t tDate;
		int nHour;
		CUtilTime ut;
		tDate = m_UtilTime.GetDate(tStartTime);
		nHour = m_UtilTime.GetHour(tStartTime);

		if (tDate != m_tmSelectedDate)
		{
			m_ListDate.SetItemIndicate(m_ListDate.GetItemIndicate()+1);
			m_ListHour.DeleteAllItems();
			m_ListHour.SetHeaderCheck(UNCHECKED);
			m_tmSelectedDate = tDate;
			SetHourList();
			m_nSelectedHour = nHour;
			m_ListHour.SetItemIndicate(0);
			m_SkinList.DeleteAllItems();
			m_SkinList.SetHeaderCheck(UNCHECKED);
			SetRecList();
		}
		else if (nHour != m_nSelectedHour)
		{
			m_nSelectedHour = nHour;
			m_ListHour.SetItemIndicate(m_ListHour.GetItemIndicate()+1);
			m_SkinList.DeleteAllItems();
			m_SkinList.SetHeaderCheck(UNCHECKED);
			SetRecList();
		}
		nStartCount = 0;

	}
	else if (nStartCount==-1)
	{
		//
		if ((m_nPlayListStart+nStartCount)<0)
			return -1;

		CTimeList *pItem = m_arrPlayList.GetAt(nStartCount+m_nPlayListStart);
		time_t tStartTime = pItem->GetStartTime();
		time_t tDate;
		int nHour;
		CUtilTime ut;
		tDate = m_UtilTime.GetDate(tStartTime);
		nHour = m_UtilTime.GetHour(tStartTime);

		if (tDate != m_tmSelectedDate)
		{
			m_ListDate.SetItemIndicate(m_ListDate.GetItemIndicate()-1);
			m_ListHour.DeleteAllItems();
			m_ListHour.SetHeaderCheck(UNCHECKED);
			m_tmSelectedDate = tDate;
			SetHourList();
			m_nSelectedHour = nHour;
			m_ListHour.SetItemIndicate(m_ListHour.GetItemCount()-1);
			m_SkinList.DeleteAllItems();
			m_SkinList.SetHeaderCheck(UNCHECKED);
			SetRecList();
		}
		else if (nHour != m_nSelectedHour)
		{
			m_nSelectedHour = nHour;
			m_ListHour.SetItemIndicate(m_ListHour.GetItemIndicate()-1);
			m_SkinList.DeleteAllItems();
			m_SkinList.SetHeaderCheck(UNCHECKED);
			SetRecList();
		}
		nStartCount = m_SkinList.GetItemCount()-1;
	}
	else if (nStartCount<-1)
		nStartCount = m_SkinList.GetItemIndicate();

	m_SkinList.SetItemIndicate(nStartCount);
	return nStartCount;
}

int CWndListTime::GetSelectedItem()
{
	return m_SkinList.GetItemIndicate();
}

CTimeList *CWndListTime::GetBackupIndex(int nIndex)
{
	CTimeList *pItem = NULL;
	if (nIndex<m_arrPlayList.GetSize())
		pItem = m_arrPlayList.GetAt(nIndex);
	return pItem;
}

//////////////////////////////////////////////////////////////////////////

void CWndListTime::ResetArray()
{
	CTimeList *ptIndex;
	while (m_arrPlayList.GetSize())
	{
		ptIndex = m_arrPlayList.GetAt(0);
		delete ptIndex;
		m_arrPlayList.RemoveAt(0);
	}

}

void CWndListTime::ResetList()
{
	m_SkinList.DeleteAllItems();

	m_ListDate.DeleteAllItems();
	m_ListHour.DeleteAllItems();

	m_bSorted = FALSE;
	ResetArray();

	m_ListDate.SetHeaderCheck(UNCHECKED);
	m_ListHour.SetHeaderCheck(UNCHECKED);
	m_SkinList.SetHeaderCheck(UNCHECKED);

	if (m_bChecked == TRUE)
	{
		NotifyCheckStatus(FALSE);
	}

	//////////////////////////////////////////////////////////////////////////
	//#417
	m_ListDate.SetItemIndicate(-1);
	m_ListHour.SetItemIndicate(-1);
	m_SkinList.SetItemIndicate(-1);
	//////////////////////////////////////////////////////////////////////////

}

void CWndListTime::ReloadRecList()
{
	if (m_arrPlayList.GetSize()<=0)
		return;
	TCHAR tzStr[64] = {0};
	CTimeList *pItemTime;
	CString strDate;
	int i;

	time_t curtm;
	time_t tm_date;
	time_t tm_date_cmp;

	int nItemCount=0;

	//1. put date
	for (i=0;i<m_arrPlayList.GetSize();i++)
	{
		pItemTime = m_arrPlayList.GetAt(i);

		curtm = pItemTime->GetStartTime();
		tm_date = m_UtilTime.GetDate(curtm);
		if (i==0)
		{
			tm_date_cmp = tm_date;
			m_UtilTime.GetDateString(curtm, tzStr);
			m_ListDate.InsertItem(nItemCount, _T(""));
			m_ListDate.SetItemText(nItemCount, 0, tzStr);
			nItemCount++;
		}
		else
		{
			if (tm_date != tm_date_cmp)
			{
				tm_date_cmp = tm_date;
				m_UtilTime.GetDateString(curtm, tzStr);
				m_ListDate.InsertItem(nItemCount, _T(""));
				m_ListDate.SetItemText(nItemCount, 0, tzStr);
				nItemCount++;
			}
		}
	}

	m_tmSelectedDate = tm_date_cmp;

	ListView_SetExtendedListViewStyle(m_ListDate.m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP /*| LVS_EX_CHECKBOXES*/);
	m_ListDate.SetItemIndicate(nItemCount-1);

	SetHourList();
	SetRecList();
}

void CWndListTime::LoadRecList()
{

	int n;
	int nCount = 0;
	CSortedArray <CTimeList *, CTimeList *> *pRecList;

	for (n=0;n<MAX_REC_TYPE;n++)
	{
		pRecList = m_pListMgr->GetRecList(n);
		if (m_bRecType[n])
		{
			nCount += pRecList->GetSize();
		}
	}
	if (nCount==0)
		return;

	MergeList();

	TCHAR tzStr[64] = {0};
	CTimeList *pItemTime;
	CString strDate;
	int i;

	time_t curtm;
	time_t tm_date;
	time_t tm_date_cmp;

	int nItemCount=0;

	//1. put date
	for (i=0;i<m_arrPlayList.GetSize();i++)
	{
		pItemTime = m_arrPlayList.GetAt(i);

		curtm = pItemTime->GetStartTime();
		tm_date = m_UtilTime.GetDate(curtm);
		if (i==0)
		{
			tm_date_cmp = tm_date;
			m_UtilTime.GetDateString(curtm, tzStr);
			m_ListDate.InsertItem(nItemCount, _T(""));
			m_ListDate.SetItemText(nItemCount, 0, tzStr);
			nItemCount++;
		}
		else
		{
			if (tm_date != tm_date_cmp)
			{
				tm_date_cmp = tm_date;
				m_UtilTime.GetDateString(curtm, tzStr);
				m_ListDate.InsertItem(nItemCount, _T(""));
				m_ListDate.SetItemText(nItemCount, 0, tzStr);
				nItemCount++;
			}
		}
	}

	m_tmSelectedDate = tm_date_cmp;

	ListView_SetExtendedListViewStyle(m_ListDate.m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP /*| LVS_EX_CHECKBOXES*/);
	m_ListDate.SetItemIndicate(nItemCount-1);

	SetHourList();
	SetRecList();
}

void CWndListTime::SetHourList(int nSelHour)
{
	int i;
	CTimeList *pItemTime;
	time_t tmCur;
	time_t tmDate;
	int nHour;
	int nHourCmp = -1;
	int nItemCount;
	TCHAR tzStr[64] = {0};

	int nSelItem = -1;

	nItemCount = 0;
	for (i=0;i<m_arrPlayList.GetSize();i++)
	{
		pItemTime = m_arrPlayList.GetAt(i);

		tmCur = pItemTime->GetStartTime();
		tmDate = m_UtilTime.GetDate(tmCur);
		if (tmDate == m_tmSelectedDate)
		{
			nHour = m_UtilTime.GetHour(tmCur);
			if (nHour != nHourCmp)
			{
				nHourCmp = nHour;
				m_UtilTime.GetHourString(tmCur, tzStr);
				m_ListHour.InsertItem(nItemCount, _T(""));
				m_ListHour.SetItemText(nItemCount, 0, tzStr);
				if (nSelHour==nHourCmp)
					nSelItem = nItemCount;
				nItemCount++;
			}
		}
	}

	if (nSelItem<0)
	{
		m_nSelectedHour = nHourCmp;
		nSelItem = nItemCount-1;
	}

	ListView_SetExtendedListViewStyle(m_ListHour.m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP /*| LVS_EX_CHECKBOXES*/);
	m_ListHour.SetItemIndicate(nSelItem);

}

void CWndListTime::SetRecList()
{
	int i;
	CTimeList *pItemTime;
	time_t tmCur;
	time_t tmDate;
	int nHour;
	int nMinCmp = -1;
	int nItemCount;
	TCHAR tzStr[64] = {0};

	nItemCount = 0;
	m_nPlayListStart = -1;
	for (i=0;i<m_arrPlayList.GetSize();i++)
	{
		pItemTime = m_arrPlayList.GetAt(i);

		tmCur = pItemTime->GetStartTime();
		tmDate = m_UtilTime.GetDate(tmCur);
		nHour = m_UtilTime.GetHour(tmCur);
		if ((tmDate == m_tmSelectedDate)&&(nHour == m_nSelectedHour))
		{
			if (m_nPlayListStart<0)
				m_nPlayListStart=i;
			m_SkinList.InsertItem(nItemCount, _T(""));
			m_UtilTime.GetTimeString(tmCur, tzStr);
			m_SkinList.SetItemText(nItemCount, 1, tzStr);

			m_SkinList.SetItemText(nItemCount, 2, m_pListMgr->GetRecTypeString(pItemTime->GetRecType()));
			nItemCount++;
		}
	}
	m_SkinList.SetRedraw(TRUE);

	m_nPlayListCount = nItemCount;		//

	ListView_SetExtendedListViewStyle(m_SkinList.m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP | LVS_EX_CHECKBOXES);

	m_SkinList.SetItemIndicate(0);
}

void CWndListTime::MergeList()
{
	int i;
	int nLoop;
	int nArr = MAX_REC_TYPE-1;
	CSortedArray <CTimeList *, CTimeList *> *pArrIndex[MAX_REC_TYPE];
	CSortedArray <CTimeList *, CTimeList *> arrRecList[MAX_REC_TYPE];
	CSortedArray <CTimeList *, CTimeList *> arrCompareTemp;
	CSortedArray <CTimeList *, CTimeList *> *pRecList;

	int m1, m2;
	BOOL bBreak;
	int nCompare;
	CTimeList *ptIndex1, *ptIndex2;
	CTimeList *ptPlayList;

	nLoop = 0;
	for (i=0;i<MAX_REC_TYPE;i++)
	{
		pRecList = m_pListMgr->GetRecList(i);
		if (m_bRecType[i] && (pRecList->GetSize()>0))
		{
			for (m1=0;m1<pRecList->GetSize();m1++)
			{
				ptIndex1 = new CTimeList();
				ptIndex2 = pRecList->GetAt(m1);
				*ptIndex1 = *ptIndex2;
				arrRecList[i].Add(ptIndex1);
			}

			pArrIndex[nLoop] = &arrRecList[i];
			nLoop++;
		}
	}

	if (nLoop==0)
		return;

	for (i=0;i<m_arrPlayList.GetSize();i++)
	{
		ptPlayList = m_arrPlayList.GetAt(i);
		delete ptPlayList;
	}
	m_arrPlayList.RemoveAll();
	if (nLoop==1)
	{
		for (i=0;i<pArrIndex[0]->GetSize();i++)
			m_arrPlayList.Add(pArrIndex[0]->GetAt(i));
	}
	else
	{
		while (TRUE)
		{
			//////////////////////////////////////////////////////////////////////////
			//merge nLoop-1 and nLoop-2 to m_arrPlayList
			m1 = 0;
			for (m2=0;m2<pArrIndex[nLoop-1]->GetSize();m2++)
			{
				ptIndex1 = pArrIndex[nLoop-1]->GetAt(m2);

				bBreak = FALSE;
				while (!bBreak)
				{
					if (m1>=pArrIndex[nLoop-2]->GetSize())
						break;

					ptIndex2 = pArrIndex[nLoop-2]->GetAt(m1);

					nCompare = ptIndex2->CompareTime(*ptIndex1);

					switch (nCompare)
					{
					case -6:
						ptPlayList = new CTimeList();
						*ptPlayList = *ptIndex2;
						ptPlayList->SetEndTime(ptIndex1->GetStartTime(), ptIndex1->GetStartMilliSec());
						m_arrPlayList.Add(ptPlayList);

						ptIndex2->SetStartTime(ptIndex1->GetEndTime(), ptIndex1->GetEndMilliSec());
						bBreak = TRUE;
						break;
					case -5:
					case -4:
						ptPlayList = new CTimeList();
						*ptPlayList = *ptIndex2;
						m_arrPlayList.Add(ptPlayList);
						m1++;
						break;
					case -3:
					case -2:
						ptPlayList = new CTimeList();
						*ptPlayList = *ptIndex2;
						ptPlayList->SetEndTime(ptIndex1->GetStartTime(), ptIndex1->GetStartMilliSec());
						m_arrPlayList.Add(ptPlayList);
						m1++;
						break;
					case -1:
					case 0:
					case 1:
					case 6:
						m1++;
						break;
					case 2:
						//				case 3:
						ptIndex2->SetStartTime(ptIndex1->GetEndTime(), ptIndex1->GetEndMilliSec());
						bBreak = TRUE;
						break;
					case 3:
						ptIndex1->SetEndTime(ptIndex2->GetStartTime(), ptIndex2->GetStartMilliSec());
						bBreak = TRUE;
						break;
					case 4:
					case 5:
						bBreak = TRUE;
						break;
					}

				}

				ptPlayList = new CTimeList();
				*ptPlayList = *ptIndex1;
				m_arrPlayList.Add(ptPlayList);
			}


			for (;m1<pArrIndex[nLoop-2]->GetSize();m1++)
			{
				ptPlayList = new CTimeList();
				ptIndex2 = pArrIndex[nLoop-2]->GetAt(m1);
				*ptPlayList = *ptIndex2;
				m_arrPlayList.Add(ptPlayList);
			}

			for (m1=0;m1<m_arrPlayList.GetSize();m1++)
			{
				ptIndex2 = m_arrPlayList.GetAt(m1);

				if (ptIndex2->GetAllInterval()<1200)
				{
					delete ptIndex2;
					m_arrPlayList.RemoveAt(m1);
					m1--;
					continue;
				}
			}

			for (m1=0;m1<pArrIndex[nLoop-2]->GetSize();m1++)
			{
				ptIndex1 = pArrIndex[nLoop-2]->GetAt(m1);
				delete ptIndex1;
			}
			pArrIndex[nLoop-2]->RemoveAll();
			
			for (m1=0;m1<pArrIndex[nLoop-1]->GetSize();m1++)
			{
				ptIndex1 = pArrIndex[nLoop-1]->GetAt(m1);
				delete ptIndex1;
			}
			pArrIndex[nLoop-1]->RemoveAll();
			//////////////////////////////////////////////////////////////////////////
			if (nLoop == 2)
			{
				break;
			}
			nLoop--;

			for (i=0;i<m_arrPlayList.GetSize();i++)
			{
				arrCompareTemp.Add(m_arrPlayList.GetAt(i));
			}
			pArrIndex[nLoop-1] = &arrCompareTemp;
			m_arrPlayList.RemoveAll();
		}
	}

}

int CWndListTime::SearchIndex(time_t tSearchTime, BOOL bFindNearBehind)
{
	int nIndex;
	BOOL bFind = FALSE;
	nIndex = binarySearchIndex(tSearchTime, 0, m_arrPlayList.GetSize()-1, &bFind);

	if (bFind)
		return nIndex;

	if (!bFindNearBehind)
		nIndex--;

	if ((nIndex<0)||(nIndex>=m_arrPlayList.GetSize()))
		return -1;
	return nIndex;
}

int CWndListTime::binarySearchIndex(time_t tSearchTime, int nStart, int nEnd, BOOL *bFind)
{
	if ((nEnd-nStart)<8)
	{
		return linearSearchIndex(tSearchTime, nStart, nEnd, bFind);
	}

	int nMid = nStart + (nEnd-nStart)/2;
	int nRet;

	CTimeList *ptIndex = m_arrPlayList.GetAt(nMid);
	nRet = ptIndex->TimeInIndex(tSearchTime, 0);
	if (nRet == 0)
	{
		*bFind = TRUE;
		return nMid;
	}
	else if (nRet<0)
		return binarySearchIndex(tSearchTime, nStart, nMid-1, bFind);
	return binarySearchIndex(tSearchTime, nMid+1, nEnd, bFind);

}

int CWndListTime::linearSearchIndex(time_t tSearchTime, int nStart, int nEnd, BOOL *bFind)
{
	int i;
	int nRet1, nRet2 = 0;
	CTimeList *ptIndex;
	*bFind = FALSE;
	for (i=nStart;i<=nEnd;i++)
	{
		ptIndex = m_arrPlayList.GetAt(i);
		nRet1 = ptIndex->TimeInIndex(tSearchTime, 0);
		if (nRet1 == 0)
		{
			*bFind = TRUE;
			return i;
		}
		else if (nRet1<0)
		{
			return i;
		}
	}
	return i;
}



BOOL CWndListTime::OnEraseBkgnd(CDC* pDC)
{
	return CWnd::OnEraseBkgnd(pDC);
}

long CWndListTime::OnPlbMessage(UINT wParam, LONG lParam)
{
	CWnd* pParent = GetParent();
	int nCtrlID = (int)wParam;

	switch (nCtrlID)
	{
	case IDC_LIST_TIME:
		if (lParam<0)
			return 0;
		m_SkinList.SetItemIndicate(lParam);
		break;
	case IDC_LIST_HOUR:
		{
			TCHAR szHour[8] = {0};
			if (lParam<0)
				return 0;
			m_ListHour.GetItemText(lParam, 0, szHour, 8);
			m_nSelectedHour = _wtoi(szHour);
			
			m_ListHour.SetItemIndicate(lParam);
			m_SkinList.DeleteAllItems();
			m_SkinList.SetHeaderCheck(UNCHECKED);
			SetRecList();

		}
		break;
	case IDC_LIST_DATE:
		{
			TCHAR szDate[16] = {0};
			TCHAR szVal[16];
			int yy, mm, dd;

			if (lParam<0)
				return 0;
			m_ListDate.GetItemText(lParam, 0, szDate, 16);
		
			memset(szVal, 0, sizeof(szVal));
			lstrcpyn(szVal, &szDate[0], 5);
			yy = _wtoi(szVal);

			memset(szVal, 0, sizeof(szVal));
			lstrcpyn(szVal, &szDate[5], 3);
			mm = _wtoi(szVal);
			memset(szVal, 0, sizeof(szVal));
			lstrcpyn(szVal, &szDate[8], 3);
			dd = _wtoi(szVal);

			m_tmSelectedDate = m_UtilTime.MakeTime(yy, mm, dd, 0, 0, 0);
			m_ListDate.SetItemIndicate(lParam);
			m_ListHour.DeleteAllItems();
			m_ListHour.SetHeaderCheck(UNCHECKED);
			SetHourList();
			m_SkinList.DeleteAllItems();
			m_SkinList.SetHeaderCheck(UNCHECKED);
			SetRecList();
			
		}
		break;
	}

	pParent->PostMessage(WM_PLB_MESSAGE, wParam, lParam);
	return 0;
}

long CWndListTime::OnCtlMessage(UINT wParam, LONG lParam)
{
	int nControlID		= LOWORD(wParam);			// Control ID
	int nMsg			= HIWORD(wParam);
	int nControlValue	= lParam;

	if (nControlID == WM_LIST_MSG)
	{
		if (nControlValue == 2)		SetCheckAll(nMsg);
		else						SetUncheckAll(nMsg);
	}
	else if (nControlID == WM_LIST_CHECK)
	{
		CSkinListCtrl *pListCtrl = (CSkinListCtrl *)GetDlgItem(nMsg);
		int i, nCnt;
		for (i=0,nCnt=0;i<pListCtrl->GetItemCount();i++)
		{
			if (pListCtrl->GetCheck(i))
				nCnt++;
		}
		if (pListCtrl->GetItemCount() == nCnt)
			pListCtrl->SetHeaderCheck(CHECKED);
		else
			pListCtrl->SetHeaderCheck(UNCHECKED);

		if (nCnt>0)
		{
			if (m_bChecked == FALSE)
				NotifyCheckStatus(TRUE);
		}
		else
		{
			if (m_bChecked == TRUE)
				NotifyCheckStatus(FALSE);
		}

	}
	else
	{
		CWnd* pParent = GetParent();
		pParent->PostMessage(WM_PLB_MESSAGE, wParam, lParam);
	}

	return 0;
}

BOOL CWndListTime::PreTranslateMessage(MSG* pMsg)
{
	return CWnd::PreTranslateMessage(pMsg);
}

void CWndListTime::NotifyCheckStatus(BOOL bChecked)
{
	CWnd *pParent = GetParent();
	m_bChecked = bChecked;
	pParent->PostMessage(WM_PLB_MESSAGE, WM_TIME_LIST_CHECK_STATUS, m_bChecked);
}

void CWndListTime::OnDestroy()
{
	CWnd::OnDestroy();

	ResetArray();
}

void CWndListTime::SetSelectRecType(DWORD dwRecType, BOOL bChecked)
{
	m_bRecType[dwRecType] = bChecked;
}

void CWndListTime::ArrangeRecList()
{
	m_SkinList.DeleteAllItems();

	m_ListDate.DeleteAllItems();
	m_ListHour.DeleteAllItems();

	int i;
	CTimeList *ptIndex;
	for (i=0;i<m_arrPlayList.GetSize();i++)
	{
		ptIndex = m_arrPlayList.GetAt(i);
		delete ptIndex;
	}
	m_arrPlayList.RemoveAll();

	MergeList();

	TCHAR tzStr[64] = {0};
	CTimeList *pItemTime;
	CString strDate;

	time_t curtm;
	time_t tm_date;
	time_t tm_date_cmp;

	int nItemCount=0;
	int nSelItem = -1;

	//1. put date
	for (i=0;i<m_arrPlayList.GetSize();i++)
	{
		pItemTime = m_arrPlayList.GetAt(i);

		curtm = pItemTime->GetStartTime();
		tm_date = m_UtilTime.GetDate(curtm);
		if (i==0)
		{
			tm_date_cmp = tm_date;
			m_UtilTime.GetDateString(curtm, tzStr);
			m_ListDate.InsertItem(nItemCount, _T(""));
			m_ListDate.SetItemText(nItemCount, 0, tzStr);
			if (m_tmSelectedDate == tm_date_cmp)
				nSelItem = nItemCount;
			nItemCount++;
		}
		else
		{
			if (tm_date != tm_date_cmp)
			{
				tm_date_cmp = tm_date;
				m_UtilTime.GetDateString(curtm, tzStr);
				m_ListDate.InsertItem(nItemCount, _T(""));
				m_ListDate.SetItemText(nItemCount, 0, tzStr);
				if (m_tmSelectedDate == tm_date_cmp)
					nSelItem = nItemCount;
				nItemCount++;
			}
		}

	}

	if (nSelItem<0)
	{
		m_tmSelectedDate = tm_date_cmp;
		nSelItem = nItemCount-1;
	}

	ListView_SetExtendedListViewStyle(m_ListDate.m_hWnd, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP /*| LVS_EX_CHECKBOXES*/);
	m_ListDate.SetItemIndicate(nSelItem);

	SetHourList(m_nSelectedHour);
	SetRecList();
}

int CWndListTime::GetRecIndexNumberFromListNumber(int nListNumber)
{
	return m_nPlayListStart + nListNumber;
}

int CWndListTime::GetCurrentRecIndexNumber()
{
	return m_nPlayListStart + m_SkinList.GetItemIndicate();
}

int CWndListTime::GetRecIndexNumberAvailable(int nIndexNumber)
{
	if ((nIndexNumber<0) || (nIndexNumber>=m_arrPlayList.GetSize()))
		return -1;
	return nIndexNumber;
}

CTimeList *CWndListTime::GetRecIndex(int nIndexNumber)
{
	return m_arrPlayList.GetAt(nIndexNumber);
}

void CWndListTime::SetRecIndex(int nIndexNumber)
{
	CTimeList *pItem;

	if ((nIndexNumber<0)||(nIndexNumber>=m_arrPlayList.GetSize()))		//#417
		return;

	pItem = m_arrPlayList.GetAt(nIndexNumber);

	time_t tStartTime = pItem->GetStartTime();
	time_t tDate;
	int nHour;
	int nItem;
	CUtilTime ut;
	tDate = m_UtilTime.GetDate(tStartTime);
	nHour = m_UtilTime.GetHour(tStartTime);

	if (tDate != m_tmSelectedDate)
	{
		TCHAR tzDateItem[64], tzDate[64];
		for (nItem=0;nItem<m_ListDate.GetItemCount();nItem++)
		{
			ZeroMemory(tzDateItem, sizeof(tzDateItem));
			ZeroMemory(tzDate, sizeof(tzDate));

			m_ListDate.GetItemText(nItem, 0, tzDateItem, 64);
			m_UtilTime.GetDateString(tStartTime, tzDate);

			if (wcscmp(tzDateItem, tzDate) == 0)
			{
				m_ListDate.SetItemIndicate(nItem);
				break;
			}
		}

		m_ListHour.DeleteAllItems();
		m_ListHour.SetHeaderCheck(UNCHECKED);
		m_tmSelectedDate = tDate;
		SetHourList();
		m_nSelectedHour = -1;

	}

	if (nHour != m_nSelectedHour)
	{
		TCHAR tzHour[8], tzHourItem[8];
		m_nSelectedHour = nHour;
		for (nItem=0;nItem<m_ListHour.GetItemCount();nItem++)
		{
			ZeroMemory(tzHour, sizeof(tzHour));
			ZeroMemory(tzHourItem, sizeof(tzHourItem));
			m_ListHour.GetItemText(nItem, 0, tzHourItem, 8);
			wsprintf(tzHour, _T("%02d"), nHour);
			if (wcscmp(tzHourItem, tzHour) == 0)
			{
				m_ListHour.SetItemIndicate(nItem);
				break;
			}
		}
		m_SkinList.DeleteAllItems();
		m_SkinList.SetHeaderCheck(UNCHECKED);
		SetRecList();
	}

	m_SkinList.SetItemIndicate(nIndexNumber-m_nPlayListStart);

}

int CWndListTime::GetRecIndexSize()
{
	return m_arrPlayList.GetSize();
}

int CWndListTime::GetBackupIndexStart()
{
	int nIndex;
	for (nIndex=0;nIndex<m_SkinList.GetItemCount();nIndex++)
	{
		if (m_SkinList.GetCheck(nIndex))
			return (nIndex + m_nPlayListStart);
	}
	return -1;
}

int CWndListTime::GetBackupIndexNext(int nIndex, BOOL bChecked)
{
	int nItem;
	nIndex++;
	if (nIndex>=m_arrPlayList.GetSize())
		return -1;

	if (bChecked)
	{
		nItem = nIndex - m_nPlayListStart;
		if (nItem<0)
			return -1;
		for (;nItem<m_SkinList.GetItemCount();nItem++)
		{
			if (m_SkinList.GetCheck(nItem))
				return (nItem + m_nPlayListStart);
		}
	}
	else
	{
		return nIndex;
	}

	return -1;
}


int CWndListTime::GetBackupIndexEnd()
{
	int nIndex = -1;
	int i;
	for (i=0;i<m_SkinList.GetItemCount();i++)
	{
		if (m_SkinList.GetCheck(i))
			nIndex = i + m_nPlayListStart;
	}

	return nIndex;
}

void CWndListTime::RefreshLang()
{
	LVCOLUMN lvCol;
	ZeroMemory(&lvCol, sizeof(lvCol));
	lvCol.mask = LVCF_TEXT;

	lvCol.pszText = (LPWSTR)(LPCTSTR)m_pListMgr->GetString(0);
	lvCol.cchTextMax = m_pListMgr->GetString(0).GetLength();
	m_ListDate.SetColumn(0, &lvCol);

	lvCol.pszText = (LPWSTR)(LPCTSTR)m_pListMgr->GetString(1);
	lvCol.cchTextMax = m_pListMgr->GetString(1).GetLength();
	m_ListHour.SetColumn(0, &lvCol);

	lvCol.pszText = (LPWSTR)(LPCTSTR)m_pListMgr->GetString(2);
	lvCol.cchTextMax = m_pListMgr->GetString(2).GetLength();
	m_SkinList.SetColumn(1, &lvCol);

	lvCol.pszText = (LPWSTR)(LPCTSTR)m_pListMgr->GetString(4);
	lvCol.cchTextMax = m_pListMgr->GetString(4).GetLength();
	m_SkinList.SetColumn(2, &lvCol);

	m_SkinList.DeleteAllItems();
	SetRecList();
	
}